<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>旋转动画</title>
    <style>
        body {
            margin: 0px;
            overflow: hidden;
        }
        canvas {
            border: 3px solid blue;
            display: block;
        }
    </style>
</head>
<body>
    <canvas id="rotating" width="1000" height="800"></canvas>
    <script type="text/javascript" src="../libs/webgl-utils.js"></script>
    <script type="text/javascript" src="../libs/shader.js"></script>
    <script id="vShader" type="x-shader/x-vertex">
        attribute vec2 a_position;
        uniform vec2 u_resolution;
        uniform mat3 u_matrix;
        varying vec4 v_color;
        void main()
        {
            vec2 position = (u_matrix * vec3(a_position, 1.0)).xy;
            vec2 zeroToone = position / u_resolution;
            vec2 clipSpace = zeroToone * 2.0 - 1.0;

            gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
            v_color = vec4(gl_Position.xyz*0.5, 0.6);
        }
    </script>
    <script id="fShader" type="x-shader/x-fragment">
        #ifdef GL_ES
        precision mediump float;
        #endif

        varying vec4 v_color;
        void main()
        {
            gl_FragColor = v_color.gbra;
        }
    </script>
    <script type="text/javascript">
        "use strict";
        let translate = [100, 400];//初始平移
        const TRANSLATE_STEP = 100;//平移幅度
        let angle = 0;//旋转角
        const ANGLE_STEP = 1.0;//旋转幅度
        let scale = [1, 1];//缩放比例
        let m3 = {
            identity: function() {
                return [
                    1, 0, 0,
                    0, 1, 0,
                    0, 0, 1
                ]
            },

            translation: function(tx, ty) {
                return [
                    1, 0, 0,
                    0, 1, 0,
                    tx, ty, 1
                ]
            },

            rotation: function(angle) {
                let c = Math.cos(angle);
                let s = Math.sin(angle);

                return [
                    c, -s, 0,
                    s, c, 0,
                    0, 0, 1
                ]
            },

            scaling: function(sx, sy) {
                return [
                    sx, 0, 0,
                    0, sy, 0,
                    0, 0, 1
                ]
            },

            multiply: function(a, b) {
                let a00 = a[0 * 3 + 0];
                let a01 = a[0 * 3 + 1];
                let a02 = a[0 * 3 + 2];
                let a10 = a[1 * 3 + 0];
                let a11 = a[1 * 3 + 1];
                let a12 = a[1 * 3 + 2];
                let a20 = a[2 * 3 + 0];
                let a21 = a[2 * 3 + 1];
                let a22 = a[2 * 3 + 2];
                let b00 = b[0 * 3 + 0];
                let b01 = b[0 * 3 + 1];
                let b02 = b[0 * 3 + 2];
                let b10 = b[1 * 3 + 0];
                let b11 = b[1 * 3 + 1];
                let b12 = b[1 * 3 + 2];
                let b20 = b[2 * 3 + 0];
                let b21 = b[2 * 3 + 1];
                let b22 = b[2 * 3 + 2];
                return [
                    b00 * a00 + b01 * a10 + b02 * a20,
                    b00 * a01 + b01 * a11 + b02 * a21,
                    b00 * a02 + b01 * a12 + b02 * a22,
                    b10 * a00 + b11 * a10 + b12 * a20,
                    b10 * a01 + b11 * a11 + b12 * a21,
                    b10 * a02 + b11 * a12 + b12 * a22,
                    b20 * a00 + b21 * a10 + b22 * a20,
                    b20 * a01 + b21 * a11 + b22 * a21,
                    b20 * a02 + b21 * a12 + b22 * a22,
                ];
            }
        };//3*3矩阵
        let position = [
            0, -100,
            150, 125,
            -175, 100
        ];//三角形顶点位置

        function main() {
            //获取canvas元素，并判断浏览器是否支持webgl
            let canvas = document.getElementById('rotating');
            let gl = canvas.getContext('webgl', {antialias:true, depth: false});
            if(!gl) {
                alert("您的浏览器不支持WebGL!");
            }

            //创建、编译并连接着色器
            let vShaderText = document.getElementById('vShader').text;
            let fShaderText = document.getElementById('fShader').text;
            let program = initShader(gl, vShaderText, fShaderText);

            //获取着色器中相关变量的位置
            program.pLocation = gl.getAttribLocation(program, 'a_position');
            program.reLocation = gl.getUniformLocation(program, 'u_resolution');
            program.mLocation = gl.getUniformLocation(program, 'u_matrix');
            program.pBuffer = gl.createBuffer();
            //创建缓冲区
            gl.bindBuffer(gl.ARRAY_BUFFER, program.pBuffer);


            //动画
            let animate = function() {
                angle = updateAngle(angle);
                translate = updateTranslate(translate[0], translate[1]);
                scale = updateSale(scale[0], scale[1]);
                drawScene(gl, program);
                requestAnimationFrame(animate);
            };

            animate();
        }
        //画图
        function drawScene(gl, program) {
            gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.useProgram(program);
            gl.enableVertexAttribArray(program.pLocation);
            gl.bindBuffer(gl.ARRAY_BUFFER, program.pBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(position), gl.STATIC_DRAW);
            gl.vertexAttribPointer(program.pLocation, 2, gl.FLOAT, false, 0, 0);
            gl.uniform2f(program.reLocation, gl.canvas.width, gl.canvas.height);

            let tMatrix = m3.translation(translate[0], translate[1]);
            let rMatrix = m3.rotation(angle);
            let sMatrix = m3.scaling(scale[0],scale[1]);
            var matrix = m3.multiply(tMatrix, rMatrix);
            matrix = m3.multiply(matrix, sMatrix);

            gl.uniformMatrix3fv(program.mLocation, false, matrix);
            gl.drawArrays(gl.TRIANGLES, 0, position.length / 2);
        }

        //实现旋转
        let r_last = Date.now();//记录开始时间
        function updateAngle(angle) {
            let now = Date.now();
            let elapsed = now - r_last;
            r_last = now;
            let newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;

            return newAngle %= 360;
        }
        //实现平移
        let t_last = Date.now();//记录开始时间
        function updateTranslate(x, y) {
            let now = Date.now();
            let elapsed = now - t_last;
            t_last = now;

            let dx = x + elapsed * TRANSLATE_STEP / 1000;
            let tx = dx;

            if (tx > 800) {
                tx = tx - dx;
               scale[0] = 1;
               scale[1] = 1;
            }

            console.log(tx);
            // let ty = y + elapsed * TRANSLATE_STEP / 1000;

            let translate =[tx, y];

            return translate;
        }
        //实现缩放
        function updateSale(sx, sy) {
            sx += Math.random() / 200;
            sy += Math.random() / 200;
            return [sx, sy];

        }
        main();
    </script>
</body>
</html>